﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Portfolio.BL.Interfaces;
using Portfolio.Entities;
using Portfolio.Repository.Common;
using Portfolio.Repository.ArticleCategories;
using Portfolio.Repository.Articles;
using Portfolio.Repository.Interfaces;
using Portfolio.BL.Dictionary;
using Portfolio.BL.Common;

namespace Portfolio.BL.ArticleCategories
{
    
    /// <summary>
    /// Klasa biznesowa Kategoria Artykułów
    /// </summary>
    public class ArticleCategoriesBL : InformationUser 
    {
       
        private ArticleCategoriesRepository _articleCategoriesRepository;
        private ArticleCategoryT _articleCategory;

        private List<ArticleCategoryT> _listDetailsViewArticleCategory;
        
        
        public ArticleCategoriesBL() : base()
        {            
            _articleCategoriesRepository = new ArticleCategoriesRepository();
            _articleCategory = new ArticleCategoryT();
            _listDetailsViewArticleCategory = new List<ArticleCategoryT>();
        }
        /// <summary>
        /// Właściwość zwraca kategorie artykułu
        /// </summary>
        public ArticleCategoryT ArticleCategory
        {
            get
            {
                return _articleCategory;
            }            
        }

        

        /// <summary>
        /// Właściwość zwraca liste kategorii artykułów dla DetailsView (formularz)
        /// </summary>
        public List<ArticleCategoryT> ListDetailsViewArticleCategory
        {
            get
            {
                return _listDetailsViewArticleCategory;
            }            
        }
        
        /// <summary>
        /// Metoda użytkownika
        /// Przypisuje wszystkie dane z konkretnej kategorii do _articleCategory
        /// </summary>
        /// <param name="idArticleCategory">id kategorii</param>
        public void SetArticleCategoryById(int pArticleCategoryID)
        {
            try
            {                
                if (pArticleCategoryID != 0)
                {
                    _articleCategory = _articleCategoriesRepository.GetArticleCategoryByIdCategory(pArticleCategoryID);
                }                              
                
            }
            catch (Exception ex)
            {
                InformationException = InformationUserDictionary.Instance.GetInformationExceptionText(1) + ex.Message;                
            }
        }

        /// <summary>
        /// Metoda użytkownika
        /// Przypisuj wyszukane kategorie artykułów do _listGridArticleCategories (GridView)
        /// </summary>
        /// <param name="title">Tytuł</param>
        /// <param name="ididCategory">Kategoria nadrzędna</param>
        /// <param name="status">Status</param>
        /// <param name="active">Aktywny</param>
        /// <param name="sortExpression">Kolumna do pososrtowania</param>
        /// <param name="sortDirection">Kierunek sortowania</param>
        /// <returns>Lista posortowanych kategorii</returns>
        public List<ArtcileCategoriesGridV> ReturnListGridArticleCategoriesBySearch(string pTitle, int? pCategoryIDID, int? pStatus, bool? pActive, string pSortExpression, string pSortDirection)
        {
            try
            {
                List<ArtcileCategoriesGridV> listGridArticleCategories;
                listGridArticleCategories = SortBy(_articleCategoriesRepository.GetArticleCategoriesBySearch(pTitle, pCategoryIDID, pStatus, pActive).AsQueryable(), pSortExpression, pSortDirection);
                foreach (ArtcileCategoriesGridV item in listGridArticleCategories)
                {
                    if (item.DepthLevel == 1)
                    {
                        item.Name = "-  " + item.Name;
                    }
                }
                return listGridArticleCategories;
            }
            catch (Exception ex)
            {
                InformationException = InformationUserDictionary.Instance.GetInformationExceptionText(1) + ex.Message;
                return null;
            }
        }

        /// <summary>
        /// Metoda użytkownika
        /// Przypisuje wszystkie dane do _listDetailsViewArticleCategory (DetailsView w formie listy)
        /// </summary>
        /// <param name="idArticleCategory">id kategorii</param>
        public void SetListDetailsViewArticleCategoryById(int pArticleCategoryID)
        {
            try
            {
                if (pArticleCategoryID != 0)
                {
                    SetArticleCategoryById(pArticleCategoryID);
                    _listDetailsViewArticleCategory.Add(_articleCategory);
                }

            }
            catch (Exception ex)
            {
                InformationException = InformationUserDictionary.Instance.GetInformationExceptionText(1) + ex.Message;
            }
        }
        

        /// <summary>
        /// Metoda użytkownika
        /// Sortuje wynik malejąco lub rosnąco wg kolumny grida
        /// </summary>
        /// <param name="source">Lista do posortowania, źródło</param>
        /// <param name="sortExpression">Określa kolumne po której będzie sortowanie</param>
        /// <param name="sortDirection">Określa kierunek sortowania</param>
        /// <returns> Lista posortowanych artykułów></returns>
        private List<ArtcileCategoriesGridV> SortBy( IQueryable<ArtcileCategoriesGridV> pSource, string pSortExpression, string pSortDirection)
        {
            switch (pSortExpression)
            {
                case "Name":
                    if (pSortDirection == "Descending")
                    {
                        pSource = pSource.OrderByDescending(p => p.Name);
                    }
                    else
                    {
                        pSource = pSource.OrderBy(p => p.Name);
                    }
                    break;

                case "ParentName":
                    if (pSortDirection == "Descending")
                    {
                        pSource = pSource.OrderByDescending(p => p.ParentName);
                    }
                    else
                    {
                        pSource = pSource.OrderBy(p => p.ParentName);
                    }
                    break;


                case "SeqAllCategory":
                    if (pSortDirection == "Descending")
                    {
                        pSource = pSource.OrderByDescending(p => p.SeqAllCategory);
                    }
                    else
                    {
                        pSource = pSource.OrderBy(p => p.SeqAllCategory);
                    }
                    break;

                case "Status":
                    if (pSortDirection == "Descending")
                    {
                        pSource = pSource.OrderByDescending(p => p.Status);
                    }
                    else
                    {
                        pSource = pSource.OrderBy(p => p.Status);
                    }
                    break;

                case "ActiveFlag":
                    if (pSortDirection == "Descending")
                    {
                        pSource = pSource.OrderByDescending(p => p.ActiveFlag);
                    }
                    else
                    {
                        pSource = pSource.OrderBy(p => p.ActiveFlag);
                    }
                    break;

                case "ModifiedDate":
                    if (pSortDirection == "Descending")
                    {
                        pSource = pSource.OrderByDescending(p => p.ModifiedDate);
                    }
                    else
                    {
                        pSource = pSource.OrderBy(p => p.ModifiedDate);
                    }
                    break;                
            }
            return pSource.ToList();
        }        

        /// <summary>
        /// Metoda użytkownika
        /// Zwraca maksymalną kolejność dla konkretnej rodziny
        /// </summary>
        /// <param name="idArticleCategory"></param>
        /// <returns>Maksymalna kolejność</returns>
        public int ReturnMaxSeqArticleCategoryById(int pArticleCategoryID)
        {
            List<ArticleCategoryT> listArticleCategories = new List<ArticleCategoryT>();
            
            try
            {                
                //listArticleCategories = _categoriesRepository.GetCategoryByIDIDCategoryIsNull(_categoriesRepository.GetCategoryByIdCategory(pArticleCategoryID).ArticleCategoryIDID);
                SetArticleCategoryById(pArticleCategoryID);
                listArticleCategories = _articleCategoriesRepository.GetArticleCategoriesByIDIDCategoryIsNull(_articleCategory.ArticleCategoryIDID);
                return listArticleCategories.Max(x => x.SeqCategory);
            }
            catch (Exception ex)
            {
                InformationException =  InformationUserDictionary.Instance.GetInformationExceptionText(3) + ex.Message;
                return 0;
            }
        }     

        
        /// <summary>
        /// Metoda użytkownika
        /// Zwiększa kolejność o jedną pozycję w górę w danej rodzinie
        /// </summary>
        /// <param name="ArticleCategory">Kategoria kliknięta</param>
        public void UpSeqArticleCategory(int pArticleCategoryID)
        {
            List<ArticleCategoryT> _listCategoriesTemp;
            List<ArticleCategoryT> _listCategoriesTemp2;
            ArticleCategoryT articleCategoryTemp2;
            try
            {                
                //kategoria zastepujaca(klikanej) _articleCategory
                SetArticleCategoryById(pArticleCategoryID);                
                //lista podkategorii zastepujacej(klikanej)
                _listCategoriesTemp = _articleCategoriesRepository.GetArticleCategoriesByIDIDCategoryIsNull(_articleCategory.ArticleCategoryID);
                //kategoria zastepowana
                articleCategoryTemp2 = _articleCategoriesRepository.GetArticleCategoryBySeqAll(_articleCategory.SeqAllCategory - 1);
                if (articleCategoryTemp2.ArticleCategoryIDID != null && articleCategoryTemp2.ArticleCategoryIDID != _articleCategory.ArticleCategoryIDID)
                {
                    articleCategoryTemp2 = _articleCategoriesRepository.GetArticleCategoryByIdCategory((int)articleCategoryTemp2.ArticleCategoryIDID);
                }
                //lista podkategorii zastepewanej
                _listCategoriesTemp2 = _articleCategoriesRepository.GetArticleCategoriesByIDIDCategoryIsNull(articleCategoryTemp2.ArticleCategoryID);
                //modyfikacja podkategorii zastepujacej kategorii                        
                using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                {
                    foreach (ArticleCategoryT item in _listCategoriesTemp)
                    {
                        item.SeqAllCategory = item.SeqAllCategory - _listCategoriesTemp2.Count - 1;
                        articleCategoryOperRepository.UpdateArticleCategory(item);
                    }
                }
                //modyfikacja zastepujacej kategorii(klikanej głównej)
                _articleCategory.SeqAllCategory = _articleCategory.SeqAllCategory - _listCategoriesTemp2.Count - 1;
                _articleCategory.SeqCategory = _articleCategory.SeqCategory - 1;
                using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                {
                    articleCategoryOperRepository.UpdateArticleCategory(ArticleCategory);
                }

                //modyfikacja podkategorii zastepowanej kategorii                        
                using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                {
                    foreach (ArticleCategoryT item in _listCategoriesTemp2)
                    {
                        item.SeqAllCategory = item.SeqAllCategory + _listCategoriesTemp.Count + 1;
                        articleCategoryOperRepository.UpdateArticleCategory(item);
                    }
                }
                //modyfikacja zastepowanej kategorii(głównej)    
                articleCategoryTemp2.SeqAllCategory = articleCategoryTemp2.SeqAllCategory + _listCategoriesTemp.Count + 1;
                articleCategoryTemp2.SeqCategory = articleCategoryTemp2.SeqCategory + 1;
                using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                {
                    articleCategoryOperRepository.UpdateArticleCategory(articleCategoryTemp2);
                }
            }
            catch (Exception ex)
            {
                InformationException = InformationUserDictionary.Instance.GetInformationExceptionText(7) + ex.Message;
            }

        }

        /// <summary>
        /// Metoda użytkownika
        /// Zmniejsza kolejność o jedną pozycję w dół w danej rodzinie
        /// </summary>
        /// <param name="ArticleCategory">Kategoria kliknięta</param>
        public void DownSeqArticleCategory(int pArticleCategoryID)
        {
            List<ArticleCategoryT> _listCategoriesTemp;
            List<ArticleCategoryT> _listCategoriesTemp2;
            ArticleCategoryT articleCategoryTemp2;
            try
            {               
                //kategoria zastepujaca(klikanej) _artcileCategory
                SetArticleCategoryById(pArticleCategoryID);                
                //lista podkategorii zastepujacej(klikanej)
                _listCategoriesTemp = _articleCategoriesRepository.GetArticleCategoriesByIDIDCategoryIsNull(_articleCategory.ArticleCategoryID);

                //kategoria zastepowana                
                articleCategoryTemp2 = _articleCategoriesRepository.GetArticleCategoryBySeqAll(_articleCategory.SeqAllCategory + _listCategoriesTemp.Count + 1);
                //lista podkategorii zastepewanej
                _listCategoriesTemp2 = _articleCategoriesRepository.GetArticleCategoriesByIDIDCategoryIsNull(articleCategoryTemp2.ArticleCategoryID);


                //modyfikacja podkategorii zastepujacej kategorii                        
                using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                {
                    foreach (ArticleCategoryT item in _listCategoriesTemp)
                    {
                        item.SeqAllCategory = item.SeqAllCategory + _listCategoriesTemp2.Count + 1;
                        articleCategoryOperRepository.UpdateArticleCategory(item);
                    }
                }
                //modyfikacja zastepujacej kategorii(klikanej głównej)
                _articleCategory.SeqAllCategory = _articleCategory.SeqAllCategory + _listCategoriesTemp2.Count + 1;
                _articleCategory.SeqCategory = _articleCategory.SeqCategory + 1;
                using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                {
                    articleCategoryOperRepository.UpdateArticleCategory(_articleCategory);
                }

                //modyfikacja podkategorii zastepowanej kategorii                        
                using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                {
                    foreach (ArticleCategoryT item in _listCategoriesTemp2)
                    {
                        item.SeqAllCategory = item.SeqAllCategory - _listCategoriesTemp.Count - 1;
                        articleCategoryOperRepository.UpdateArticleCategory(item);
                    }
                }
                //modyfikacja zastepowanej kategorii(głównej)    
                articleCategoryTemp2.SeqAllCategory = articleCategoryTemp2.SeqAllCategory - _listCategoriesTemp.Count - 1;
                articleCategoryTemp2.SeqCategory = articleCategoryTemp2.SeqCategory - 1;
                using (ArticleCategoryOperRepository articleCategoryOperRepository = new ArticleCategoryOperRepository())
                {
                    articleCategoryOperRepository.UpdateArticleCategory(articleCategoryTemp2);
                }
            }
            catch (Exception ex)
            {
                InformationException = InformationUserDictionary.Instance.GetInformationExceptionText(7) + ex.Message;
            }
        }

        public Boolean ReturnDDLArticleCategoryEnabled(int pArticleCategoryID)
        {
            try
            {
                using (ArticleCategoriesRepository articleCategoriesRepository = new ArticleCategoriesRepository())
                {
                    if (articleCategoriesRepository.GetCountArticleCategoryChildByArticleCategoryID(pArticleCategoryID) > 0)
                    {
                        return false;
                    }
                    else
                    {
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                InformationException = InformationUserDictionary.Instance.GetInformationExceptionText(7) + ex.Message;
                return false;
            }
        }

    }    
}
